<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Invocation Lists</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Invocation Lists' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">values</a></li><li><a href="index.html#4">Chapter 4: The S-Parser</a></li><li><b>Invocation Lists</b></li></ul></div>
<p class="purpose">Invocation lists are lists of alternate readings of the same wording to invoke a phrase.</p>

<ul class="toc"><li><a href="4-il.html#SP1">&#167;1. Introduction</a></li><li><a href="4-il.html#SP2">&#167;2. Creation and conversion</a></li><li><a href="4-il.html#SP3">&#167;3. Operations on lists</a></li><li><a href="4-il.html#SP7">&#167;7. Sorting the invocation list</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Introduction.</b>Here is a "To..." phrase definition, and then a rule making two invocations of it:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">To</span><span class="plain-syntax"> </span><span class="identifier-syntax">advance</span><span class="plain-syntax"> (</span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">piece</span><span class="plain-syntax"> - </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">chess</span><span class="plain-syntax"> </span><span class="identifier-syntax">piece</span><span class="plain-syntax">) </span><span class="identifier-syntax">by</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> - </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">number</span><span class="plain-syntax">):</span>
<span class="plain-syntax">    ...</span>

<span class="identifier-syntax">Every</span><span class="plain-syntax"> </span><span class="identifier-syntax">turn</span><span class="plain-syntax">:</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">advance</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">pawn</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">advance</span><span class="plain-syntax"> </span><span class="identifier-syntax">false</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax">:21 </span><span class="identifier-syntax">PM</span><span class="plain-syntax">.</span>
</pre>
<p class="commentary">An invocation is a usage of a phrase in a particular case, so here the every
turn rule is making two invocations. Even control structures in Inform are
phrases, so in fact every line of an imperative definition is exactly one
invocation.
</p>

<p class="commentary">Clearly only the first of these invocations makes sense in terms of what the
phrase is being applied to. The truth state "false" is not a chess piece, and
the time "10:21 PM" is not a number. So this invocation will certainly lead
to problem messages being issued, but it is an invocation just the same.
</p>

<p class="commentary">Invocations are stored in the parse tree. The above "every turn" rule comes
out thus:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">IMPERATIVE_NT</span><span class="plain-syntax"> </span><span class="string-syntax">"every turn"</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">CODE_BLOCK_NT</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax"> </span><span class="string-syntax">"advance the pawn by 2"</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">INVOCATION_NT</span><span class="plain-syntax"> </span><span class="string-syntax">"advance the pawn by 2"</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax"> </span><span class="string-syntax">"advance the pawn by 2"</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">INVOCATION_NT</span><span class="plain-syntax"> </span><span class="string-syntax">"advance false by 10:21 PM"</span>
</pre>
<p class="commentary">Each line of the original definition corresponds to an <span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span>
node: the possible readings of the text as an invocation are then listed as its
children, which are all <span class="extract"><span class="extract-syntax">INVOCATION_NT</span></span> nodes. In this example the text was
unambiguous, but for a definition like this:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">Every</span><span class="plain-syntax"> </span><span class="identifier-syntax">turn</span><span class="plain-syntax">:</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">let</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">good</span><span class="plain-syntax"> </span><span class="identifier-syntax">old</span><span class="plain-syntax"> </span><span class="identifier-syntax">stand</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="identifier-syntax">be</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">random</span><span class="plain-syntax"> </span><span class="identifier-syntax">bishop</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">advance</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">good</span><span class="plain-syntax"> </span><span class="identifier-syntax">old</span><span class="plain-syntax"> </span><span class="identifier-syntax">stand</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary">...the second line can now be read in two different ways:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">advance</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">good</span><span class="plain-syntax"> </span><span class="identifier-syntax">old</span><span class="plain-syntax"> </span><span class="identifier-syntax">stand</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="plain-syntax">            ~~~~~~~~~~~~~~~~~~    ~~~~</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">advance</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">good</span><span class="plain-syntax"> </span><span class="identifier-syntax">old</span><span class="plain-syntax"> </span><span class="identifier-syntax">stand</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="identifier-syntax">by</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="plain-syntax">            ~~~~~~~~~~~~~~~~~~~~~    ~</span>
</pre>
<p class="commentary">These possibilities each become <span class="extract"><span class="extract-syntax">INVOCATION_NT</span></span> nodes, and therefore the invocation
list for the line has two entries. Those two nodes are joined with <span class="extract"><span class="extract-syntax">next_alternative</span></span>
links, not <span class="extract"><span class="extract-syntax">next</span></span> links, since they are alternative readings of the same text: they
cannot both be right.
</p>

<p class="commentary">Finally, it is worth noting three complications:
</p>

<ul class="items"><li>(a) Invocation lists arise from expressions as well as from entire code lines,
much as functions in C can be used in expressions, <span class="extract"><span class="extract-syntax">int x = f(2);</span></span> as well
as in void context, <span class="extract"><span class="extract-syntax">printf("I do have a return value, you know! Nobody cares.")</span></span>.
<ul class="items"><li>(1) See <a href="../assertions-module/2-is.html" class="internal">Imperative Subtrees (in assertions)</a> for how invocation lists for the body
of imperative definitions are put together.
</li><li>(2) See <a href="4-cap.html" class="internal">Conditions and Phrases</a> for how invocation lists from expressions
are put together.
</li></ul>
<li>(b) "Say" phrases are a special case, in that they can perform more than one
invocation. <span class="extract"><span class="extract-syntax">say "Very cold for [time of day], I think?"</span></span> performs three
invocations &mdash; one of <span class="extract"><span class="extract-syntax">say (T - text)</span></span>, one of <span class="extract"><span class="extract-syntax">say (T - time)</span></span>, and then
another of <span class="extract"><span class="extract-syntax">say (T - text)</span></span>. These three invocations are joined by <span class="extract"><span class="extract-syntax">-&gt;next</span></span>
not <span class="extract"><span class="extract-syntax">-&gt;next_alternative</span></span> links because all three must be performed.
</li><li>(c) A small number of invocations for adaptive text do not invoke phrases,
but instead print an inflected form of a verb, adjective or similar.
</li></ul>
<p class="commentary">In this section, we provide basic functions for dealing with invocation lists;
similarly, <a href="4-inv.html" class="internal">Invocations</a> provides tools for dealing with individual invocations;
and in <a href="4-pi.html" class="internal">Parse Invocations</a> we show how to refine the bare syntax tree for a
definition into the above parse tree structure. But choosing between the
readings, and compiling the result, is done much deeper in the compiler: see
<a href="../imperative-module/5-cbal.html" class="internal">Compile Blocks and Lines (in imperative)</a> for more.
</p>

<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Creation and conversion.</b>Lists are sometimes made new, and sometimes converted from existing but less
thoroughly parsed parts of the syntax tree:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">InvocationLists::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">InvocationLists::new</span></span>:<br/>Conditions and Phrases - <a href="4-cap.html#SP12_1">&#167;12.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CompilationUnits::assign_to_same_unit</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">InvocationLists::new_singleton</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">InvocationLists::new_singleton</span></span>:<br/>Conditions and Phrases - <a href="4-cap.html#SP10">&#167;10</a>, <a href="4-cap.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="4-il.html#SP2" class="function-link"><span class="function-syntax">InvocationLists::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">InvocationLists::make_into_list_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Node::set_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Operations on lists.</b>Once lists are created, we tend to represent them not by a pointer to the
<span class="extract"><span class="extract-syntax">INVOCATION_LIST_NT</span></span> node but with a pointer to <span class="extract"><span class="extract-syntax">first_inv</span></span>, the first of the
invocations in the list, i.e., the child of the list node.
</p>

<p class="commentary">Using that convention, where <span class="extract"><span class="extract-syntax">NULL</span></span> represents the empty list, this extends
the list by one:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">InvocationLists::add_alternative</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">InvocationLists::add_alternative</span></span>:<br/>Conditions and Phrases - <a href="4-cap.html#SP12_1">&#167;12.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">) </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>For convenience, there is a cap on the length of invocation lists, though
at least it is preposterously high:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_INVOCATIONS_PER_PHRASE</span><span class="plain-syntax"> </span><span class="constant-syntax">4096</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>The following macro abstracts the process of looping through the invocations
in such a list:
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">)</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>And again using this convention, we get:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">InvocationLists::first_reading</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InvocationLists::length</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">InvocationLists::length</span></span>:<br/><a href="4-il.html#SP7">&#167;7</a><br/>Conditions and Phrases - <a href="4-cap.html#SP12">&#167;12</a><br/>Dash - <a href="5-dsh.html#SP10_9_2_4">&#167;10.9.2.4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">) </span><span class="identifier-syntax">L</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">InvocationLists::log</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Invocation list (%d):\n"</span><span class="plain-syntax">, </span><a href="4-il.html#SP6" class="function-link"><span class="function-syntax">InvocationLists::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"P%d: $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">++, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">InvocationLists::log_in_detail</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="4-il.html#SP6" class="function-link"><span class="function-syntax">InvocationLists::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"P%d/%d: $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">++, </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="plain-syntax">&lt;</span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"  %d: $P\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">tok</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">INVOCATION_LIST_NT</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><a href="4-il.html#SP6" class="function-link"><span class="function-syntax">InvocationLists::log_in_detail</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Sorting the invocation list.</b>This is crucial to the correct running of the compiler, since invocations
earlier in the list are more likely to be accepted than later. The list is
never very long, so performance is not an issue here, but it's a nuisance to
sort a linked list: we must stash it into an array called <span class="extract"><span class="extract-syntax">pigeon_holes</span></span>,
sort that, and then convert it back into a linked list again.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv_data</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unsorted_position</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pigeon_holes</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">number_of_pigeon_holes</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>

<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">InvocationLists::sort</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">InvocationLists::sort</span></span>:<br/>Conditions and Phrases - <a href="4-cap.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="4-il.html#SP6" class="function-link"><span class="function-syntax">InvocationLists::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="4-il.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Make sure there are at least L pigeonholes available for sorting into</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="4-il.html#SP7_2" class="named-paragraph-link"><span class="named-paragraph">Copy the list of alternatives into the pigeonholes</span><span class="named-paragraph-number">7.2</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="identifier-syntax">qsort</span><span class="plain-syntax">(</span><span class="identifier-syntax">pigeon_holes</span><span class="plain-syntax">, (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><a href="4-il.html#SP8" class="function-link"><span class="function-syntax">InvocationLists::sort_cmp</span></a><span class="plain-syntax">);</span>

<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="4-il.html#SP7_3" class="named-paragraph-link"><span class="named-paragraph">Copy the pigeonholes back into the list of alternatives</span><span class="named-paragraph-number">7.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure invocation_sort_block is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1" class="paragraph-anchor"></a><b>&#167;7.1. </b>We allocate 1000 pigeonholes in the first instance, then double each time
we run out. (We will quite likely never run out, as 1000 is plenty. But we
want to avoid all possible arbitrary limits.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make sure there are at least L pigeonholes available for sorting into</span><span class="named-paragraph-number">7.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">number_of_pigeon_holes</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">number_of_pigeon_holes</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">*</span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">number_of_pigeon_holes</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1000</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">number_of_pigeon_holes</span><span class="plain-syntax"> = </span><span class="constant-syntax">1000</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pigeon_holes</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Memory::calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">number_of_pigeon_holes</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax">),</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">INV_LIST_MREASON</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-il.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_2" class="paragraph-anchor"></a><b>&#167;7.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Copy the list of alternatives into the pigeonholes</span><span class="named-paragraph-number">7.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ent</span><span class="plain-syntax">=</span><span class="identifier-syntax">first_inv</span><span class="plain-syntax">; (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">L</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ent</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++, </span><span class="identifier-syntax">ent</span><span class="plain-syntax">=</span><span class="identifier-syntax">ent</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pigeon_holes</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">inv_data</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ent</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pigeon_holes</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">unsorted_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-il.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_3" class="paragraph-anchor"></a><b>&#167;7.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Copy the pigeonholes back into the list of alternatives</span><span class="named-paragraph-number">7.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tail</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">L</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i_n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pigeon_holes</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">inv_data</span><span class="plain-syntax">; </span><span class="identifier-syntax">i_n</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tail</span><span class="plain-syntax">) </span><span class="identifier-syntax">tail</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i_n</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i_n</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">tail</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i_n</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-il.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>So much for the mechanism. The sorting order ranks invocations first (a) by
logical priority of phrases &mdash; see <a href="../assertions-module/5-tpf.html" class="internal">To Phrase Family (in assertions)</a>; then,
in cases of a tie, (b) by the order in which the excerpt parser found the
possible reading.
</p>

<p class="commentary">Note that sequence counts for phrases, and unsorted positions in the list,
are both unique. This is important since it means <a href="4-il.html#SP8" class="internal">InvocationLists::sort_cmp</a>
never produces a tie (i.e. returns 0) unless <span class="extract"><span class="extract-syntax">i1 == i2</span></span>; so the fact that <span class="extract"><span class="extract-syntax">qsort</span></span>
applies an unstable sorting algorithm does not affect the result &mdash; we are
exactly defining the order of the list.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">InvocationLists::sort_cmp</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">InvocationLists::sort_cmp</span></span>:<br/><a href="4-il.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i1</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax"> *</span><span class="identifier-syntax">isb1</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">i1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax"> *</span><span class="identifier-syntax">isb2</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">invocation_sort_block</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">i2</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> (a) sort by logical priority of phrases</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">delta</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ToPhraseFamily::sequence_count</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">isb1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inv_data</span><span class="plain-syntax">)) -</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ToPhraseFamily::sequence_count</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">isb2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inv_data</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">delta</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">delta</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> (b) sort by creation sequence</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">isb1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unsorted_position</span><span class="plain-syntax"> - </span><span class="identifier-syntax">isb2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unsorted_position</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="4-cap.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-vm.html">1</a></li><li class="progresschapter"><a href="2-spc.html">2</a></li><li class="progresschapter"><a href="3-pl.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-ets.html">ets</a></li><li class="progresssection"><a href="4-cad.html">cad</a></li><li class="progresssection"><a href="4-teav.html">teav</a></li><li class="progresssection"><a href="4-varc.html">varc</a></li><li class="progresssection"><a href="4-cap.html">cap</a></li><li class="progresscurrent">il</li><li class="progresssection"><a href="4-inv.html">inv</a></li><li class="progresssection"><a href="4-pi.html">pi</a></li><li class="progresschapter"><a href="5-dsh.html">5</a></li><li class="progressnext"><a href="4-inv.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

